<?php

/*
 *  
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * 
 * Copyright 2015 Max Group. All rights reserved.
 * 
 */

namespace BLL\DAO;

use BLL\DataModel as DM;

/**
 * Description of JSonReader
 *
 * @author david
 */
class JSonReader {

    private $model;
    private $master;

    private $masterID;
    private $rootID;
    public $data;
    
    public function __construct($nodeName, $master = null) {
        if ($master) {
            $this->master = $master;
            $this->model = $master->getDataModel()->nodes[$nodeName];
            $t1 = $this->master->getDataModel()->idField;
            $t2 = $this->model->masterNode->getRootIDField();
            $this->masterID = $this->master->{$this->master->getDataModel()->idField};
            if(strval($this->masterID) === "0"){
                $i=1;
                exit();
            }

        $this->rootID = $this->master->{$this->model->masterNode->getRootIDField()};
        } else {
            $this->model = DM\DataNodeDescription::getNodeByNameTrail($nodeName);
            $this->rootID = $this->{$this->model->idField};
        }
        $this->data = call_user_func(array($this->model->getFullName(), 'create'));
        $this->generateSelAttr();
    }

    public function readFile($fileName) {
        //\Log::info(time()."Begin read file".$fileName."\r\n");
        $str = file_get_contents($fileName);
        $this->readString($str);
//        \Log::info(time()."End read file".$fileName."\r\n");

    }
    
    public function readString($string){
        $_jsonObject = json_decode($string,true);
        $this->readFromJSonObject($_jsonObject);
    }

    public function readFromJsonObject($_jsonObject) {
        $tempArr = explode("\\", $this->model->jsonBase);
        $jo = $_jsonObject;
        foreach ($tempArr as $temp) {
            if($temp!=""){
                $jo = $jo[$temp];
            }
        }
        if (!$this->model->jsonAttributesToArray) {
            $this->readNormalSection($jo);
        } else {
            $this->readAttrToArraySection($jo);
        } 
    }

    private function readNormalSection($_jsonObject) {
    //    $modelObjs = array();
        $cnt = 0;
        $temp = $this->model->getFullName();
        if($temp === "AppModel\\Application\\BankStatement\\Analysis"){
            $i=0;
        }
        if($temp === "AppModel\Application\BankStatement\\DayEndBalance"){
            $i=0;
        }
        echo time()."Begin To Load ".$this->model->getFullName().", Total:".count($_jsonObject)."<br>";
        foreach ($_jsonObject as $jsonRow) {
            $row = array();
            $skip = false;
            foreach ($this->model->items as $item) {
                $key = $item->name;
                $value = $this->readSingleValue($jsonRow, $item->jsonValueItem ,$item);
                $row[$key] = $value;
            }
            if($skip){
                continue;
            }
            $this->setDataObject($row);
            var_dump($this->data->getAttributes());
//            $this->data->save();
            $this->readSonNodes($jsonRow, $this->data);
//            echo $obj->get();
//            exit();
            $cnt++;
        }
        echo time()."End Load ".$this->model->getFullName().", Total:".$cnt."<br>";
    }

    private function readAttrToArraySection($_jsonObject) {
        $omits = array();
        $cnt = 0;
        if ($this->model->jsonAttributesToArrayOmit) {
            $omits = explode(",", $this->model->jsonAttributesToArrayOmit);
        }
        $temp = $this->model->getFullName();
        if($temp === "AppModel\\Application\\BankStatement\\Analysis"){
            $i=0;
        }
        if($temp === "AppModel\Application\BankStatement\\DayEndBalance"){
            $i=0;
        }
        
        echo time()."Begin To Load ".$this->model->getFullName().", Total:".count($_jsonObject)."<br>";
        foreach ($_jsonObject as $key => $value) {
            $skip = false;
            if (in_array($key, $omits, false))
                continue;
            $row = array();
            foreach ($this->model->items as $item) {
                if ($item->jsonAttribute) {
                    $row[$item->name] = $jo = \BLL\DataModel\DataType::getValueFromString($item->dataType, $key);
                } else {
                    if ($item->jsonValueItem === "#value#") {
                        $v = $value;
                    } else {
                        $v = $this->readSingleValue($value, $item->jsonValueItem, $item);
                    }
                    if ( $item->jsonSkipWhenEqual === $v ) {
                        $skip = true;
                        break;
                    }
                    $row[$item->name] = $v;
                }
            }
            if($skip){
                continue;
            }
            $cnt++;
            $this->setDataObject($row);
            var_dump($this->data->getAttributes());
//            $this->data->save();
        ////            echo $obj->get();
//            exit();
            $this->readSonNodes($value, $this->data);
        }
        echo time()."End Load ".$this->model->getFullName().", Total:".$cnt."<br>";
        
//        return $modelObjs;
    }

    private function readSingleValue($_jsonObject, $path, $item) {
        $tempArr = explode("\\", $path);
        $jo = $_jsonObject;
        foreach ($tempArr as $temp) {
            if ($temp != "") {
                //$jo = $jo->{$temp};
                $jo = $jo[$temp];
            }
        }
        if($item->jsonSpecial){
            if($item->jsonSpecial=="toString"){
                if (is_array($jo)) {
                    $jo = implode(",", $jo);
                }
            }
        }
        $jo = \BLL\DataModel\DataType::getValueFromString($item->dataType, $jo);
        return $jo;
    }

    private function setDataObject(array $attributes = null) {
        if ($attributes) {
            if (count($this->selAttrs) > 0) {
                $sel = array();
                foreach ($this->selAttrs as $key) {
                    if ($key === $this->model->masterIDField) {
                        $sel[$key] = $this->masterID;
                    } else {
                        $sel[$key] = $attributes[$key];
                    }
                }
                $this->data = $this->data->firstOrNew($sel);
            }else{
                $this->data = $this->data->create();
            }
            $this->data->fill($attributes);
            if(!$this->data->{$this->model->idField}){
                $this->data->{$this->model->idField} = uniqid();
            }
        }else{
            $this->data = $this->data->create();
            $this->data->{$this->model->idField} = uniqid();
        }
  
        if ($this->model->getRootIDField()) {
            $this->data->{$this->model->getRootIDField()} = $this->rootID;
        }
        
        $this->data->MasterNode()->associate($this->master);
    }

    private $selAttrs = null;

    private function generateSelAttr() {
        if ($this->selAttrs) {
            return $this->selAttrs;
        }
        $firstUG = null;
        foreach ($this->model->items as $item) {
            if (!$item->uniqueGroup) {
                continue;
            }
            if (!$firstUG) {
                $firstUG = $item->uniqueGroup;
                $this->selAttrs = array();
                if ($this->model->masterNode) {
                    array_push($this->selAttrs, $this->model->masterIDField);
                }
            }
            if ($firstUG != $item->uniqueGroup) {
                continue;
            }
            array_push($this->selAttrs, $item->fieldName);
        }
        return $this->selAttrs;
    }

//    private function readSonNodes($_jsonObject, $modelObjs, $obj) {
    private function readSonNodes($_jsonObject, $obj) {
        foreach ($this->model->nodes as $node) {
            $t1 = $obj->getDataModel()->idField;
            $oo = $obj->{$t1};
            if(strval($oo)==="0"){
                $i=1;
            }
            
            $sonReader = new JSonReader($node->name, $obj);
//            $sonModelObjs = $sonReader->readFromJsonObject($_jsonObject);
            $sonReader->readFromJsonObject($_jsonObject);
//            $modelObjs = array_merge($modelObjs, $sonModelObjs);
        }
//        return $modelObjs;
    }

}
